﻿using System;
using System.Collections.ObjectModel;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using Bricks;
using Bricks.Injecting;

namespace Motar.ServiceModel
{
    
    /// <summary>
    /// 
    /// </summary>
    public class ExceptionHandlingServiceBehavior : FacadeBase<IValueResolver<IErrorHandler>>, IServiceBehavior
    {

        /// <summary>
        /// 
        /// </summary>
        public ExceptionHandlingServiceBehavior() :
            this(new SingleValueResolver<IErrorHandler>())
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="key"></param>
        public ExceptionHandlingServiceBehavior(string key) :
            this(new SingleValueResolver<IErrorHandler>(key))
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="errorHandlerResolver"></param>
        public ExceptionHandlingServiceBehavior(IValueResolver<IErrorHandler> errorHandlerResolver) :
            base(() => errorHandlerResolver)
        {
            if (errorHandlerResolver == null)
            {
                throw new ArgumentNullException("errorHandlerResolver");
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceDescription"></param>
        /// <param name="serviceHostBase"></param>
        /// <param name="endpoints"></param>
        /// <param name="bindingParameters"></param>
        public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection<ServiceEndpoint> endpoints, BindingParameterCollection bindingParameters)
        {
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceDescription"></param>
        /// <param name="serviceHostBase"></param>
        public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
            Execute(errorHandlerResolver =>
            {
                foreach (ChannelDispatcher channelDispatcher in serviceHostBase.ChannelDispatchers)
                {
                    channelDispatcher.ErrorHandlers.Add(errorHandlerResolver.Resolve());
                }
            });
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="serviceDescription"></param>
        /// <param name="serviceHostBase"></param>
        public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
        {
        }
    }
}
